package com.ywu.data.source.standard.source.field;

import com.ywu.data.source.standard.dto.YwuDataTableFieldDto;
import com.ywu.data.source.standard.entity.YwuDataTableEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName YwuBuildFieldCommon
 * @Description TODO
 * @Author GroundDemo
 * @Date 2024/10/28 21:06
 * @Version 1.0
 **/
@Component
public class YwuBuildFieldCommon {

    @Autowired
    private List<YwuDataSourceFieldSqlBuild> dataSourceFieldSqlBuildList;

    /**
     * @Author GroundDemo
     * @Description 构建字段的sql
     * @Date 19:01 2024/10/28
     * @Param [ywuDataTableEntity, field]
     * @return java.lang.String
     **/
    public String buildFieldInfoSql(YwuDataTableEntity ywuDataTableEntity, YwuDataTableFieldDto field) {
        StringBuilder sql = new StringBuilder();
        for (YwuDataSourceFieldSqlBuild build : dataSourceFieldSqlBuildList) {
            sql.append(build.buildSql(ywuDataTableEntity, field));
        }
        return sql.toString();
    }

    /**
    * @Author GroundDemo
    * @Description 重命名表名称
    * @Date 21:19 2024/10/28
    * @Param [oldEntity, newEntity]
    * @return java.lang.String
    **/
    public String renameTableNameSql(YwuDataTableEntity oldEntity, YwuDataTableEntity newEntity) {
        return String.format("ALTER TABLE %s RENAME TO %s;", oldEntity.getTableName(), newEntity.getTableName());
    }

    /**
    * @Author GroundDemo
    * @Description 比较历史字段和原始字段是否一致
    * @Date 21:34 2024/10/28
    * @Param [oldEntity, newEntity]
    * @return java.util.Map<java.lang.String,java.util.List<com.ywu.data.source.standard.dto.YwuDataTableFieldDto>>
    **/
    public Map<String, List<YwuDataTableFieldDto>> compareField(YwuDataTableEntity oldEntity, YwuDataTableEntity newEntity) {
        Map<String, List<YwuDataTableFieldDto>> resMap = new HashMap<>();
        // 根据ID构建出map
        List<YwuDataTableFieldDto> oldFieldInfo = oldEntity.getFieldInfo();
        Map<String, YwuDataTableFieldDto> oldFieldMap = oldFieldInfo.stream().collect(Collectors.toMap(YwuDataTableFieldDto::getId, res -> res, (v1, v2) -> v1));
        List<YwuDataTableFieldDto> newFieldInfo = newEntity.getFieldInfo();
        Map<String, YwuDataTableFieldDto> newFieldMap = newFieldInfo.stream().collect(Collectors.toMap(YwuDataTableFieldDto::getId, res -> res, (v1, v2) -> v1));
        // 比较需要添加的数据
        Set<String> oldIds = oldFieldMap.keySet();
        Set<String> newIds = newFieldMap.keySet();
        List<YwuDataTableFieldDto> addDto = new ArrayList<>();
        for (String idKey : newIds) {
            if (!oldIds.contains(idKey)) {
                addDto.add(newFieldMap.get(idKey));
            }
        }
        resMap.put("add", addDto);
        List<YwuDataTableFieldDto> deleteDto = new ArrayList<>();
        List<YwuDataTableFieldDto> updateDto = new ArrayList<>();
        for (String idKey : oldIds) {
            if (!newIds.contains(idKey)) {
                deleteDto.add(oldFieldMap.get(idKey));
            } else {
                YwuDataTableFieldDto newDto = newFieldMap.get(idKey);
                YwuDataTableFieldDto oldDto = oldFieldMap.get(idKey);
                newDto.setOldName(oldDto.getName());
                newDto.setOldPrimaryKey(oldDto.getPrimaryKey());
                updateDto.add(newDto);
            }
        }
        resMap.put("delete", deleteDto);
        resMap.put("update", updateDto);
        return resMap;
    }

    /**
    * @Author GroundDemo
    * @Description 删除字段的sql
    * @Date 9:10 2024/10/29
    * @Param [deleteList]
    * @return java.lang.String
    **/
    public String buildDeleteColFieldInfoSql(List<YwuDataTableFieldDto> deleteList) {
        StringBuilder resSql = new StringBuilder();
        for (YwuDataTableFieldDto field : deleteList) {
            resSql.append(String.format("DROP COLUMN `%s`,", field.getName()));
        }
        return resSql.toString();
    }

    /**
    * @Author GroundDemo
    * @Description 添加字段的sql
    * @Date 9:13 2024/10/29
    * @Param [addList,ywuDataTableEntity]
    * @return java.lang.String
    **/
    public String buildAddColFieldInfoSql(List<YwuDataTableFieldDto> addList, YwuDataTableEntity ywuDataTableEntity) {
        StringBuilder resSql = new StringBuilder();
        for (YwuDataTableFieldDto field : addList) {
            String sql = buildFieldInfoSql(ywuDataTableEntity, field);
            resSql.append(String.format("ADD COLUMN %s,", sql));
        }
        return resSql.toString();
    }

    /**
    * @Author GroundDemo
    * @Description 修改字段的sql
    * @Date 9:21 2024/10/29
    * @Param [updateList, newEntity]
    * @return java.lang.String
    **/
    public String buildUpdateColFieldInfoSql(List<YwuDataTableFieldDto> updateList, YwuDataTableEntity ywuDataTableEntity) {
        StringBuilder resSql = new StringBuilder();
        for (YwuDataTableFieldDto field : updateList) {
            boolean isPrimaryKey = false;
            if (field.getPrimaryKey()) {
                isPrimaryKey = true;
                field.setPrimaryKey(false);
            }
            String sql = buildFieldInfoSql(ywuDataTableEntity, field);
            resSql.append(String.format("CHANGE COLUMN `%s` %s,", field.getOldName(), sql));
            if (isPrimaryKey) {
                if (field.getOldPrimaryKey()) {
                    resSql.append(String.format("DROP PRIMARY KEY,ADD PRIMARY KEY (`%s`) USING BTREE,", field.getName()));
                } else {
                    resSql.append(String.format("ADD PRIMARY KEY (`%s`) USING BTREE,", field.getName()));
                }
            }
        }
        return resSql.toString();
    }
}
